public class Prototype implements Cloneable {

    public static void main(String[] args) throws CloneNotSupportedException {
        Prototype p1 = new Prototype();
        p1.ValueProperty = 1;
        p1.ReferenceProperty = new RefType();

        Prototype p2 = (Prototype) p1.clone();
        Prototype p3 = (Prototype) p1.deepClone();

        p2.ValueProperty = 2;
        p3.ValueProperty = 3;

        System.out.println(p1.ValueProperty);
        System.out.println(p2.ValueProperty);
        System.out.println(p3.ValueProperty);

        System.out.println(p1.ReferenceProperty.hashCode());
        System.out.println(p2.ReferenceProperty.hashCode());
        System.out.println(p3.ReferenceProperty.hashCode());
    }

    public int ValueProperty;
    public RefType ReferenceProperty;

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public Object deepClone() throws CloneNotSupportedException {
        Prototype p = new Prototype();
        p.ValueProperty = this.ValueProperty;
        if (this.ReferenceProperty != null) {
            p.ReferenceProperty = (RefType) this.ReferenceProperty.clone();
        }
        return p;
    }
}

class RefType implements Cloneable {
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}